package com.cantor.cantorspringbootstarter.processor;

import cn.hutool.core.util.StrUtil;
import com.cantor.cantorspringbootstarter.anno.CantorService;
import com.cantor.cantorspringbootstarter.tool.InjectionUtil;
import com.cantor.core.center.RegistrationCenter;
import com.cantor.core.config.CantorAppConfig;
import com.cantor.provider.pojo.ServiceBoat;
import com.cantor.provider.regsitry.ServiceRegistrant;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;

/**
 * 扫描每一个Bean, 头上有@CantorService注解的,注册进CantorServiceRegistrant
 */
@Slf4j
public class ServiceRegisterProcessor implements BeanPostProcessor {

    @Autowired
    ApplicationContext applicationContext;

    @Autowired
    CantorAppConfig cantorAppConfig;

    @Autowired
    RegistrationCenter center;

    @Autowired
    ServiceRegistrant serviceRegistrant;

    @SneakyThrows
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> serviceClz = bean.getClass();
        if (!serviceClz.isAnnotationPresent(CantorService.class)) {
            return bean;
        }
        CantorService serviceAnn = serviceClz.getDeclaredAnnotation(CantorService.class);
        Class<?>[] interfaces = serviceClz.getInterfaces();
        if (interfaces.length == 0) {
            return bean;
        }
        // 如果这个Impl实现了多个接口, 那么将注册多个服务.
        for (Class<?> anInterface : interfaces) {
            // 如果某个接口没有方法则跳过.
            if (anInterface.getMethods().length < 1) {
                continue;
            }
            doRegister(bean, anInterface, serviceAnn);
        }
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    private void doRegister(Object serviceImpl, Class<?> anInterface, CantorService serviceAnn) throws Exception {
        ServiceBoat serviceBoat = new ServiceBoat();
        serviceBoat.setServiceInterface(anInterface);
        serviceBoat.setServiceImpl(serviceImpl);
        String version = serviceAnn.version();
        if (StrUtil.isNotBlank(version)) {
            serviceBoat.setVersion(version);
        }
        int timeout = serviceAnn.timeout();
        if (InjectionUtil.isDefaultValue(timeout)) {
            serviceBoat.setTimeout(timeout);
        }
        int weight = serviceAnn.weight();
        if (weight > 0) {
            serviceBoat.setWeight(weight);
        }
        String mock = serviceAnn.mock();
        if (StrUtil.isNotBlank(mock)) {
            serviceBoat.setMock(mock);
        }
        serviceRegistrant.register(serviceBoat);
        log.debug("BeanPostProcessor已将{}放入map",anInterface.getName());
    }
}
